<template>
  <div class="cesium">
    <div class="cesium" id="cesiumContainer"></div>
    <div id="showInfo"></div>
  </div>
</template>

<script>
//引入Cesium样式
import 'cesium/Build/Cesium/Widgets/widgets.css' //样式
import * as Cesium from 'cesium'

const {Viewer, UrlTemplateImageryProvider} = Cesium
import flightData from "@/assets/json/plane.json";

let cesiumMap = null
let airplaneEntity = null

export default {
  name: "cesium",
  props: {
    lists: {
      type: Array,
      default: () => {
        return []
      }
    },
    list: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      isA: false,
      options: {},
    }
  },
  watch: {
    list(val, oldval) {
      // console.log(999, val)
      if (!cesiumMap) {
        return false
      }
      if (oldval && val) {
        let heading = this.courseAngle(oldval.longitude, oldval.latitude, val.longitude, val.latitude)
        let posArr = [oldval, val]
        this.updatePosition(val, heading, posArr)
      } else {
        this.updatePosition(val)
      }
    }
  },
  mounted() {
    /* 默认亚洲经纬度 */
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
      90,
      -20,
      110,
      90
    );
    cesiumMap = new Viewer("cesiumContainer", {
      // imageryProvider: new UrlTemplateImageryProvider({
      //   // 下面是我的瓦片地址部署在本地，可以根据自己实际修改
      //   url: 'http://192.168.110.205:8888' + '/satellite/{z}/{x}/{y}.jpg',
      //   fileExtension: "jpg"
      // }),
      shouldAnimate: false, // 自动播放
      animation: false, // 是否显示动画控件
      homeButton: false, // 是否显示home键
      geocoder: false, // 是否显示地名查找控件
      baseLayerPicker: false, // 是否显示图层选择控件
      timeline: false, // 是否显示时间线控件
      fullscreenButton: false, // 是否全屏显示
      scene3DOnly: true, // 如果设置为true，则所有几何图形以3D模式绘制以节约GPU资源
      infoBox: false, // 是否显示点击要素之后显示的信息
      sceneModePicker: false, // 是否显示投影方式控件  三维/二维
      navigationInstructionsInitiallyVisible: false,
      navigationHelpButton: false, // 是否显示帮助信息控件
      selectionIndicator: false, // 是否显示指示器组件
      // 注释时相当于使用默认地形，解开注释相当于使用全球地形
      terrainProvider: Cesium.createWorldTerrain()
    });

    // viewer.imageryLayers.addImageryProvider(new UrlTemplateImageryProvider({
    //   url: 'http://localhost:8080' + '/tms/overlay/{z}/{x}/{y}.png',
    //   fileExtension: "png"
    // }));

    // 判断是否支持图像渲染像素化处理
    if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
      cesiumMap.resolutionScale = window.devicePixelRatio;
    }
    // 开启抗锯齿
    cesiumMap.scene.fxaa = true;
    cesiumMap.scene.postProcessStages.fxaa.enabled = true;

    this.initScene('/static/Cesium_Air.glb', true, 0, 0, 500000, 0, 0, 0)
    // this.drawLine()
    // this.drawPolyline()
  },
  methods: {
    initScene(modelURL, isShowInfo, longitude, latitude, height, heading, pitch, roll) {
      // 指定位置
      let position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
      //指定姿态
      let hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading), Cesium.Math.toRadians(pitch), Cesium.Math.toRadians(roll));
      let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

      let entity = cesiumMap.entities.add({
        id: "myEntity",
        //自己指定的位置
        position: position,
        //使用自己指定的姿态角
        orientation: orientation,
        model: {
          uri: modelURL,  //飞机模型
          minimumPixelSize: 64
        },
        // Show the path as a pink line sampled in 1 second increments.
        // 绘制轨迹线
        path: new Cesium.PathGraphics({
          width: 1,
        }),
      })
    },
    drawPolyline() {
      let primitive = new Cesium.Primitive({
        geometryInstances: new Cesium.GeometryInstance({
          geometry: new Cesium.PolylineGeometry({
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
              0.0, 0.0, 1000, 118.0, 0.0, 5000
            ]),
            width: 1,
            vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT
          }),
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0))
          }
        }),
        appearance: new Cesium.PolylineColorAppearance({
          translucent: false
        })
      });
      cesiumMap.scene.primitives.add(primitive);
    },
    // 画线
    drawLine(arr) {
      if (arr.length >= 2) {

      }
      //加轨迹线
      let lineData = [arr[0].longitude, arr[0].latitude, arr[0].height, arr[1].longitude, arr[1].latitude, arr[1].height];
      let entities = cesiumMap.entities.add({
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights(lineData),
          width: 5,
          material: new Cesium.Color.fromCssColorString("#FF0000"),
          clampToGround: true
        }
      })
    },
    // 更新位置
    updatePosition(item, headingNum = 0, posArr = []) {
      let d = new Date();
      let t = d.toLocaleTimeString();

      let position = new Cesium.Cartesian3();
      position = Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, item.height);//(经度，纬度，高程)

      let gheading = Cesium.Math.toRadians(headingNum); // 航向角
      let gpitch = Cesium.Math.toRadians(0); // 俯仰角
      let groll = Cesium.Math.toRadians(0); // 横滚角

      let hpr = new Cesium.HeadingPitchRoll(gheading, gpitch, groll);
      let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

      //更新位置
      cesiumMap.entities.getById("myEntity").position = position;
      //更新姿态
      cesiumMap.entities.getById("myEntity").orientation = orientation;

      // this.drawLine(posArr)

    },
    // 这个计算的是逆时针,如果需要顺时针,可以在返回的结果里+360即可.
    courseAngle(lng_a, lat_a, lng_b, lat_b) {
      let startLat = this.toRadians(lat_a);
      let startLng = this.toRadians(lng_a);
      let destLat = this.toRadians(lat_b);
      let destLng = this.toRadians(lng_b);

      let y = Math.sin(destLng - startLng) * Math.cos(destLat);
      let x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
      let brng = Math.atan2(y, x);
      let brngDgr = this.toDegrees(brng);
      return (brngDgr + 270) % 360;
    },
    // Converts from degrees to radians.
    toRadians(degrees) {
      return degrees * Math.PI / 180;
    },
    // Converts from radians to degrees.
    toDegrees(radians) {
      return radians * 180 / Math.PI;
    },
  }
}
</script>

<style scoped lang="scss">
  .cesium {
    height: 100%;
    width: 100%;

    ::v-deep.cesium-widget-credits {
      display: none !important;
      visibility: hidden !important;
    }
  }
</style>